package com.hisense.ovcloud.commons.configs.activemq;

import cn.hutool.core.lang.Opt;
import com.hisense.ovcloud.commons.constants.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.Order;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.annotation.JmsListenerConfigurer;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerEndpointRegistrar;
import org.springframework.jms.config.JmsListenerEndpointRegistry;
import org.springframework.jms.config.SimpleJmsListenerEndpoint;
import org.springframework.stereotype.Component;

import javax.jms.Message;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

@Component
@Slf4j
@EnableJms
@ConditionalOnProperty(prefix = "amq", name = "brokerUrl")
@Order(1000)
public class JMSDynamicRegistrator implements JmsListenerConfigurer, ApplicationContextAware {
    private final JmsListenerContainerFactory<?> jmsListenerContainerQueue;
    private final JmsListenerContainerFactory<?> jmsListenerContainerTopic;
    private final AMQProps activeMQConf;

    private Map<String, AMQConsumer> consumerMap;

    public JMSDynamicRegistrator(AMQProps activeMQConf, JmsListenerContainerFactory<?> jmsListenerContainerQueue,
                                 JmsListenerContainerFactory<?> jmsListenerContainerTopic) {
        this.activeMQConf = activeMQConf;
        this.jmsListenerContainerQueue = jmsListenerContainerQueue;
        this.jmsListenerContainerTopic = jmsListenerContainerTopic;
    }

    @Override
    public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
        JmsListenerEndpointRegistry registry = Opt.ofNullable(registrar.getEndpointRegistry()).orElse(new JmsListenerEndpointRegistry());

        activeMQConf.getConfigs().forEach(config -> config.getDynamicTopics().forEach(topicConfig -> {
                    SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
                    endpoint.setId(UUID.randomUUID().toString());
                    endpoint.setDestination(topicConfig.getTopicName());
                    endpoint.setConcurrency(topicConfig.getConcurrencty());
                    endpoint.setMessageListener((Message message) -> {
                        try {
                            consumerMap.get(topicConfig.getBeanName()).consume(message);
                        } catch (Exception e) {
                            log.error(e.getMessage());
                        }
                    });

                    try {
                        if (config.getType().equals(Constants.AMQ.MSG_TYPE_QUEUE)) {
                            registry.registerListenerContainer(endpoint, jmsListenerContainerQueue, true);
                        } else {
                            registry.registerListenerContainer(endpoint, jmsListenerContainerTopic, true);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

        ));
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        consumerMap = Optional.of(applicationContext.getBeansOfType(com.hisense.ovcloud.commons.configs.activemq.AMQConsumer.class)).orElse(new HashMap<>());
    }
}
